﻿package frEngine.core.mesh
{
    import baseEngine.basic.*;
    import baseEngine.core.*;
    import baseEngine.modifiers.*;
    import baseEngine.system.*;
    import flash.events.*;
    import flash.geom.*;
    import frEngine.*;
    import frEngine.animateControler.keyframe.*;
    import frEngine.animateControler.particleControler.*;
    import frEngine.core.*;
    import frEngine.effectEditTool.manager.*;
    import frEngine.event.*;
    import frEngine.loaders.resource.info.*;
    import frEngine.manager.*;
    import frEngine.pools.*;
    import frEngine.render.*;
    import frEngine.render.layer.*;
    import frEngine.shader.filters.fragmentFilters.*;
    import frEngine.shader.filters.vertexFilters.*;
    import frEngine.util.*;

    public class ParticleMesh extends Mesh3D
    {
        private var _vertexFilter:ParticleVertexFilter;
        private var _particleFileData:ParticleFileData;
        private var _particleUrl:String;
        private var _useOuterParams:Boolean;
        private var _useRotation:Boolean = false;
        private var _useScale:Boolean = true;
        public var useTargetEndPoint:Boolean;
        public var hangToTemple:Boolean;
        private var _hangObjUid:String;
        private var _hangBoneName:String;
        private var _hangObj:Pivot3D;
        public var particleControler:ParticleAnimateControler;

        public function ParticleMesh(param1:String)
        {
            super(param1, false, null);
            if (Global3D.useGpuParticle)
            {
                this._vertexFilter = new ParticleVertexFilter();
            }
            else
            {
                this._vertexFilter = new ParticleVertexFilter_CPU();
            }
            this.material.materialParams.depthWrite = false;
            this.material.materialParams.twoSided = false;
            this.setMateiralBlendMode(EBlendType.BLEND_LIGHT);
            this.setLayer(Layer3DManager.particleLayer);
            this.particleControler = this.getAnimateControlerInstance(AnimateControlerType.ParticleAnimateControler) as ParticleAnimateControler;
            return;
        }// end function

        public function get hangObjPoint() : Vector3D
        {
            var _loc_1:Vector3D = null;
            if (!this._hangObj || !this.useTargetEndPoint)
            {
                throw new Error("没有应用挂到结束点");
            }
            if (this._hangObj is Md5Mesh)
            {
                _loc_1 = this.getPos(Md5Mesh(this._hangObj), this._hangBoneName);
            }
            else
            {
                _loc_1 = this._hangObj.getPosition(false);
            }
            return _loc_1;
        }// end function

        public function setUseScale(param1:Boolean) : void
        {
            param1 = true;
            if (param1 == this._useScale)
            {
                return;
            }
            this._useScale = param1;
            this.particleControler.useScale = this._useScale;
            this.material.materialParams.needRebuild = true;
            return;
        }// end function

        public function setTargetEndPoint(param1:Boolean, param2:String, param3:String, param4:Boolean) : void
        {
            var _loc_5:* = param1;
            this.useTargetEndPoint = param1;
            this.particleControler.useTargetEndPoint = _loc_5;
            this._hangObjUid = param2;
            this._hangBoneName = param3;
            this.hangToTemple = param4;
            this._hangObj = null;
            return;
        }// end function

        override protected function toUpdateModifier() : void
        {
            var _loc_3:Modifier = null;
            var _loc_1:int = 50;
            var _loc_2:int = 0;
            for each (_loc_3 in _animateControlerList)
            {
                
                _loc_2++;
                if (_loc_3 != this.particleControler)
                {
                    _loc_3.toUpdateAnimate();
                }
                if (_loc_2 > _loc_1)
                {
                    break;
                }
            }
            this.particleControler.toUpdateAnimate();
            return;
        }// end function

        public function initHangObj(param1:Obj3dContainer, param2:Pivot3D = null) : void
        {
            if (param2)
            {
                this._hangObj = param2;
            }
            else if (this.hangToTemple)
            {
                this._hangObj = param1.temple.getMeshByUid(this._hangObjUid);
            }
            else
            {
                this._hangObj = param1.getObject3dByID(this._hangObjUid) as Mesh3D;
            }
            return;
        }// end function

        private function getPos(param1:Md5Mesh, param2:String = "Bip001 Pelvis") : Vector3D
        {
            var resultPoint3d:Vector3D;
            var joint:Vector3D;
            var _globlePos:Vector3D;
            var targetMd5:* = param1;
            var boneName:* = param2;
            if (boneName)
            {
                try
                {
                    joint = targetMd5.targetMd5Controler.getGJointPoseByName(boneName);
                    resultPoint3d = targetMd5.world.transformVector(joint);
                }
                catch (e:Error)
                {
                    boneName;
                }
            }
            if (!boneName)
            {
                _globlePos = new Vector3D();
                targetMd5.world.copyColumnTo(3, _globlePos);
                resultPoint3d = _globlePos;
            }
            return resultPoint3d;
        }// end function

        public function setUseRotation(param1:Boolean) : void
        {
            if (param1 == this._useRotation)
            {
                return;
            }
            this._useRotation = param1;
            this.particleControler.useRotation = this._useRotation;
            this.material.materialParams.needRebuild = true;
            return;
        }// end function

        public function reinit(param1:String, param2:RenderList, param3:Boolean = false) : void
        {
            this.renderList = param2;
            this._useOuterParams = param3;
            if (param1)
            {
                this.particleUrl = param1;
            }
            return;
        }// end function

        public function get canImpStop() : Boolean
        {
            var _loc_1:* = this._particleFileData ? (this._particleFileData.particleParams) : (null);
            var _loc_2:* = !_loc_1 || !_loc_1.tailEnabled || _loc_1.total_number == 1;
            return _loc_2;
        }// end function

        public function get particleUrl() : String
        {
            return this._particleUrl;
        }// end function

        public function set particleUrl(param1:String) : void
        {
            if (this._particleUrl && this._particleUrl != param1)
            {
                Resource3dManager.instance.unLoad(this._particleUrl, this.parseHasLoadedBytes);
            }
            this._particleUrl = param1;
            if (param1)
            {
                Resource3dManager.instance.load(param1, this.parseHasLoadedBytes, loadPriority);
                this.priority = HelpUtils.getSortIdByName(param1);
            }
            return;
        }// end function

        private function parseHasLoadedBytes(param1:ParticleInfo) : void
        {
            this.particleFileData = param1.particleFileData;
            FrEventDispatcher.instance.proxyDispatchEvent(this, Engine3dEventName.PARSE_MESH_FINISH);
            return;
        }// end function

        override public function dispose(param1:Boolean = true) : void
        {
            if (this._particleUrl)
            {
                Resource3dManager.instance.unLoad(this._particleUrl, this.parseHasLoadedBytes);
                this._particleUrl = null;
            }
            if (this._particleFileData)
            {
                FrEventDispatcher.instance.proxyRemoveEventListener(this._particleFileData, Engine3dEventName.InitComplete, this.particleInitComplete);
                this._particleFileData = null;
            }
            this.setUseRotation(false);
            this.setUseScale(false);
            this.setTargetEndPoint(false, null, null, false);
            super.dispose(param1);
            return;
        }// end function

        public function get particleFileData() : ParticleFileData
        {
            return this._particleFileData;
        }// end function

        public function set particleFileData(param1:ParticleFileData) : void
        {
            if (this._particleFileData)
            {
                FrEventDispatcher.instance.proxyRemoveEventListener(this._particleFileData, Engine3dEventName.InitComplete, this.particleInitComplete);
            }
            this._particleFileData = param1;
            if (!this._particleFileData)
            {
                return;
            }
            if (this._particleFileData.particleParams && this._particleFileData.particleParams.hasCompleted)
            {
                this.particleInitComplete(null);
            }
            else
            {
                this.particleControler.particleParams = null;
                this._vertexFilter.particleFileData = null;
                FrEventDispatcher.instance.proxyAddEventListener(this._particleFileData, Engine3dEventName.InitComplete, this.particleInitComplete);
            }
            return;
        }// end function

        private function particleInitComplete(event:Event) : void
        {
            FrEventDispatcher.instance.proxyRemoveEventListener(this._particleFileData, Engine3dEventName.InitComplete, this.particleInitComplete);
            var _loc_2:* = this._particleFileData.particleParams;
            _loc_2.uvRepeat = this.material.materialParams.uvRepeat;
            this.particleControler.particleParams = _loc_2;
            this._vertexFilter.particleFileData = this._particleFileData;
            if (!this._useOuterParams)
            {
                this.material.materialParams.twoSided = _loc_2.doubleFace;
                this.setMateiralBlendMode(_loc_2.blendType);
            }
            return;
        }// end function

        override public function clearAllControlers(param1:Boolean) : void
        {
            super.clearAllControlers(param1);
            this.particleControler = this.getAnimateControlerInstance(AnimateControlerType.ParticleAnimateControler) as ParticleAnimateControler;
            this.particleControler.useRotation = this._useRotation;
            this.particleControler.useScale = this._useScale;
            this.particleControler.useTargetEndPoint = this.useTargetEndPoint;
            return;
        }// end function

        override public function removeAnimateControler(param1:int) : void
        {
            super.removeAnimateControler(param1);
            if (param1 == AnimateControlerType.LineRoadControler)
            {
                this.particleControler.lineRoadControler = null;
            }
            return;
        }// end function

        override public function getAnimateControlerInstance(param1:int, param2:Modifier = null) : Modifier
        {
            var _loc_3:* = super.getAnimateControlerInstance(param1, param2);
            if (_loc_3 == null)
            {
                switch(param1)
                {
                    case AnimateControlerType.ParticleAnimateControler:
                    {
                        if (Global3D.useGpuParticle)
                        {
                            _loc_3 = param2 ? (param2) : (FrObjectPool.getObject(ParticleAnimateControler, this));
                        }
                        else
                        {
                            _loc_3 = param2 ? (param2) : (FrObjectPool.getObject(New_ParticleAnimateControler2, this));
                        }
                        this.particleControler = ParticleAnimateControler(_loc_3);
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
                if (_loc_3)
                {
                    _animateControlerList[param1] = _loc_3;
                    _loc_3.targetObject3d = this;
                    if (_loc_3 is IRender)
                    {
                        this.render = IRender(_loc_3);
                    }
                }
            }
            if (param1 == AnimateControlerType.LineRoadControler)
            {
                this.particleControler.lineRoadControler = LineRoadControler(_loc_3);
            }
            return _loc_3;
        }// end function

        override public function setShaderBase(param1:VertexFilter, param2:FragmentFilter) : void
        {
            super.setShaderBase(this._vertexFilter, param2);
            return;
        }// end function

    }
}
